#pragma once
#include <tuple>
#include "base.h"
namespace Temp
{
    template<typename T>
        struct FunctionTraits;
    template<typename R,typename... Args>
        struct FunctionHelps
        {
            using ReturnType = R;
            using ArgList = TypeList<Args...>;
            static constexpr auto paramCount = sizeof...(Args);
            template <std::size_t N>
            using paramType =typename std::tuple_element<N,std::tuple<Args...>>::type;

            using types = typename std::tuple<Args...>;

            /*
               template<std::size_t N>
               using paramType = std:t<N, std::tuple<Args...>>;
               */
        };
    //fun()
    template<typename R,typename... Args>
        struct FunctionTraits<R(Args...)> : public FunctionHelps<R,Args...>
        {
        };
    //(*fun)()
    template<typename R, typename... Args>
        struct FunctionTraits<R(*)(Args...)> : public FunctionHelps<R, Args...>
        {
        };
    //(&fun)()
    template<typename R, typename... Args>
        struct FunctionTraits<R(&)(Args...)> : public FunctionHelps<R, Args...>
        {
        };
    //针对lambda函数
    template<typename ClassType , typename R, typename... Args>
        struct FunctionTraits<R(ClassType::*)(Args...) const> : public FunctionHelps<R, Args...>
        {
            using class_type = ClassType;
        };
    template<typename ClassType , typename R, typename... Args>
        struct FunctionTraits<R(ClassType::*)(Args...) > : public FunctionHelps<R, Args...>
        {
            using class_type = ClassType;
        };

    template<typename T>
        struct FunctionTraits : public FunctionTraits<decltype(&T::operator())>
    {
    };
    template<typename T>
    struct FunctionTraits<T&> : public FunctionTraits<T>
    {
    };
    template<typename T>
    struct FunctionTraits<T&&> : public FunctionTraits<T>
    {
    };





}
